package com.toutiao.score


import scala.math.{max,min}

class SimScorer {
  
  
  val p = """(\[.*?\])|(\《.*?\》)|(\“.*?\”)|(\【.*?\】)|(\(.*?\))|(\".*?\")|(\（.*?\）)""".r // 括号词
  val u = """([0-9]+年)|([0-9]+月[0-9]+日)""".r // 时间词  
  
  def getMatchScore(m1:Topic,m2:Topic):Double = {
    
	  val title1 = m1.m("t").reduce(_+_)
	  val title2 = m2.m("t").reduce(_+_)
	  
	  val mp1 = p.findAllIn(title1).toArray.map(v => {
	    v.slice(1, v.size-1)
	  }).filter(_.size < 8)
	  val mp2 = p.findAllIn(title2).toArray.map(v => {
	    v.slice(1,v.size-1)
	  }).filter(_.size < 8)
	  val mu1 = u.findAllIn(title1).toArray
	  val mu2 = u.findAllIn(title2).toArray
	  
	  val mm1 = mp1++mu1
	  val mm2 = mp2++mu2
	  
	  val s1 =
	    if (mm1.size == 0)
	      mm1.size
	    else
	      mm1.map(v => {  if (title2.contains(v)) 1 else 0 }).reduce(_+_)
	      
	  val s2 = 
	    if (mm2.size == 0)
	      mm2.size
	    else
	      mm2.map(v => { if (title1.contains(v)) 1 else 0}).reduce(_+_)
	  
	  
	  if (mm1.size > 0 && s1 == mm1.size && mm2.size > 0 && s2 == mm2.size)
		  1.0
	  else
	      0.0
  }

  def getImageMatchScore(mg1: Array[String], mg2: Array[String]) = {

    if (mg1.size == 0 || mg2.size == 0)
      0
    else {
      val gs = mg1.flatMap(g1 => {
        val z1 = BigInt(g1)
        mg2.map(g2 => {
          val z2 = BigInt(g2)
          if (z1 > z2)
            (z1, z2)
          else
            (z2, z1)
        })
      }).toSet.filter(x => {
        x._1 != x._2
      })

      val ss = gs.map(x => {
        val g1 = x._1
        val g2 = x._2
        val cc = TextSignature.countEquals(g1, g2)
        cc
      }).filter(_ > 52)

      ss.size
    }

  }  
  
  private
  def cos(m1:Map[String,Double], s1:Double, m2:Map[String,Double], s2:Double):Double = {
   SimpleFactory.cos(m1,s1,m2,s2)
  }
  
  def getSimScore(m1:Topic,m2:Topic):Double = {
    val s = getMatchScore(m1,m2)
    if (s > 0)
      cos(m1.v,m1.s,m2.v,m2.s)
    else
      s
  }

  def getCharacterMatch(title1: Array[String], title2: Array[String]) = {
    //val title1 = m1.title.reduce(_+_)
    //val title2 = m2.title.reduce(_+_)

    if (title1.size == 0 || title2.size == 0) {
      0.0
    } else {
      val t1 = title1.reduce(_ + _).toArray.toSet
      val t2 = title2.reduce(_ + _).toArray.toSet

      val t = t1 & t2

      val ss = t.size.toDouble

      val uu = min(30, max(t1.size, t2.size))

      min(1.0, ss / uu)
    }

  }
  
  def getSimScore(m1:Topic, m2:Topic, S:Double) = {
    val s1 = cos(m1.v,m1.s,m2.v,m2.s)
    val s2 = getMatchScore(m1,m2)
    val s3 = getImageMatchScore(m1.m("e"),m2.m("e")) // 图片重复
    val s4 = getCharacterMatch(m1.m("e"),m2.m("e")) // 字符重复
    
    val ss = 0.6
    
    if (s1 > S){
      s1
    }
    else {
      if (s1 > ss && s2 > 0.0){
        S+0.01
      }
      else if (s3 > 0.0){
        S+0.02
      }
      else if (s1 > ss && s4 > 0.8){
        S+0.03
      }
      else {
        s1
      }
    }
    
  }
  
  // *************************************************************************
  
  def test1(title1:String, title2:String) = {
    val t1 = title1.toArray.toSet
    val t2 = title2.toArray.toSet
    
    val t = t1 & t2
    
    println(t.size+" "+t1.size+" "+t2.size)
  }
  
  def test2(cutTitle1:String, cutTitle2:String) = {
    val t1 = cutTitle1.split(" ").toSet
    val t2 = cutTitle2.split(" ").toSet
    
    val t = t1 & t2
    
    println(t.size+" "+t1.size+" "+t2.size)
  }
  
  
}

//object TestSimCase extends App {
//  
//  val title1 = "快讯：戴尔宣布670亿美元收购数据存储巨头EMC"
//  val title2 = "科技界最大并购案诞生 戴尔670亿美元收购EMC"
//    
//  val cutTitle1 = "快讯 ： 戴尔 宣布 670 亿 美元 收购 数据 存储 巨头 EMC"
//  val cutTitle2 = "科技界 最大 并购案 诞生 戴尔670亿 美元 收购 EMC"
//    
//  val simScorer = new SimScorer
//  
//  simScorer.test1(title1,title2)
//  simScorer.test2(cutTitle1,cutTitle2)
//  
//  val ct1 = cutTitle1.split(" ")
//  val ct2 = cutTitle2.split(" ")
//  
//  val s  = simScorer.getCharacterMatch(ct1, ct2)
//  
//  println(s)
//  
//}
